package com.baiyue.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baiyue.entity.TableSet;
import com.baiyue.enums.TableSetEnum;
import com.baiyue.exception.GlobalException;
import com.baiyue.manager.CashierManger;
import com.baiyue.mapper.TableSetMapper;
import com.baiyue.model.CashierResult;
import com.baiyue.model.SelectOptionsResult;
import com.baiyue.model.charging.ChargingDataRequest;
import com.baiyue.model.charging.ChargingDataResponse;
import com.baiyue.model.tableSet.TableSetDataRequest;
import com.baiyue.model.tableSet.TableSetDataResponse;
import com.baiyue.result.CodeMsg;
import com.baiyue.service.ChargingService;
import com.baiyue.service.TableSetService;
import com.baiyue.utils.BeanMapperUtil;
import com.baiyue.utils.UserHolderUtil;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 * @author 伍波
 * @date 2024-04-30
 */
@Service
public class TableSetServiceImpl implements TableSetService {
    private static final Logger logger = LoggerFactory.getLogger(TableSetServiceImpl.class);

    @Autowired
    private TableSetMapper tableSetMapper;

    @Autowired
    private ChargingService chargingService;

    @Autowired
    private CashierManger cashierManger;
    /**
     * 新增包间
     * @param request
     */
    @Override
    public void insertTableSet(TableSetDataRequest request){
        logger.info("新增包间入参:{}", JSONObject.toJSONString(request));
        if (StringUtils.isEmpty(request.getRoomName())){
            logger.warn("房间号为空，新增失败");
            throw new GlobalException(CodeMsg.BIND_ERROR.fillArgs("房间号"));
        }
        if (request.getMinimumSpend() == 1){
            if (Objects.isNull(request.getMinimumPurchaseAmount())){
                logger.warn("最低消费为是，但最低消费金额为空！！！");
                throw new GlobalException(CodeMsg.BIND_ERROR.fillArgs("最低消费金额"));
            }
        }
        if(Objects.isNull(request.getState())){
            request.setState(0);
        }
        TableSet tableSet = tableSetMapper.getTableSetByTableName(request.getRoomName());
        if (Objects.nonNull(tableSet)){
            throw new GlobalException(CodeMsg.ALREADY_EXISTS.fillArgs("房间号"));
        }
        TableSet insertTableSet = BeanMapperUtil.map(request, TableSet.class);
        insertTableSet.setCreateTime(new Date());
        insertTableSet.setUpdateTime(new Date());
        String user = UserHolderUtil.getUser().getUsername();
        insertTableSet.setCreateBy(user);
        insertTableSet.setUpdateBy(user);
        tableSetMapper.insert(insertTableSet);
    }

    /**
     * 修改包间信息
     * @param request
     * @return
     */
    @Override
    public Boolean updateTableSet(TableSetDataRequest request){
        logger.info("修改包间信息入参:{}", JSONObject.toJSONString(request));
        if (StringUtils.isEmpty(request.getRoomName())){
            TableSet tableSet = tableSetMapper.getTableSetByTableName(request.getRoomName());
            if (Objects.nonNull(tableSet)){
                logger.warn("包间号重复！！！");
                throw new GlobalException(CodeMsg.ALREADY_EXISTS.fillArgs("包间号"));
            }
        }
        String user = UserHolderUtil.getUser().getUsername();
        TableSet tableSet = BeanMapperUtil.map(request, TableSet.class);
        tableSet.setUpdateBy(user);
        tableSet.setUpdateTime(new Date());
        Integer res = tableSetMapper.updateById(tableSet);
        return res > 0;
    }

    /**
     * 获取所有包间信息
     * @param request
     * @return
     */
    @Override
    public List<TableSetDataResponse> getTableSetData(TableSetDataRequest request) {
        logger.info("获取所有包间信息");
        TableSet tableSet = BeanMapperUtil.map(request, TableSet.class);
        List<TableSet> tableSetList = tableSetMapper.findAll(tableSet);
        List<TableSetDataResponse> responseList = BeanMapperUtil.mapList(tableSetList, TableSetDataResponse.class);

        // 获取非空包间的 UUID 列表
        List<String> uuidList = responseList.stream()
                .filter(tableSetDataResponse -> tableSetDataResponse.getState() != 0)
                .map(TableSetDataResponse::getUuid)
                .collect(Collectors.toList());

        // 获取对应的 CashierResult 列表
        List<CashierResult> resultList = uuidList.isEmpty() ? Collections.emptyList() : getTime(uuidList);

        // 构建房间号与 CashierResult 的映射关系
        Map<String, CashierResult> roomToCashierResultMap = resultList.stream()
                .collect(Collectors.toMap(CashierResult::getRoomNumber, Function.identity()));

        // 设置 categoryChar 并将 CashierResult 设置到相应的 TableSetDataResponse 中
        responseList.forEach(tableSetDataResponse -> {
            tableSetDataResponse.setCategoryChar(TableSetEnum.getTableSet(tableSetDataResponse.getCategory()).getValue());
            tableSetDataResponse.setCashierResult(roomToCashierResultMap.get(tableSetDataResponse.getRoomName()));
        });

        return responseList;
    }

    public List<SelectOptionsResult> getSelectOptions(){
        logger.info("获取包间类型下拉框");
        List<SelectOptionsResult> results = tableSetMapper.findIdAndName();

        if (results.isEmpty()){
            logger.warn("获取包间类型下拉框为空");
            return Collections.emptyList();  // 使用Collections.emptyList()而非new ArrayList<>()
        }

        results.forEach(result -> {
            TableSetEnum tableSetEnum = TableSetEnum.getTableSet(result.getValue());
            if (tableSetEnum != null) {
                result.setLabel(tableSetEnum.getValue());
            } else {
                logger.warn("无效的表集合类型值: {}" , result.getValue());
            }
        });

        return results;
    }
    public List<CashierResult> getTime(List<String> uuids) {
        if (uuids == null || uuids.isEmpty()) {
            logger.warn("UUID列表为空，无法查询信息");
            return Collections.emptyList(); // 返回空列表而不是 null
        }

        ChargingDataRequest request = new ChargingDataRequest();
        request.setUuidS(uuids);
        List<ChargingDataResponse> responses = chargingService.findByUuid(request);

        List<CashierResult> results = new ArrayList<>();
        for (ChargingDataResponse response : responses) {
            CashierResult result = cashierManger.calculateTimeDuration(
                    response.getStartTime(),response.getPauseStartTime(),response.getStatus(),response.getPauseMinutes(),
                    null
            );
            result.setRoomNumber(response.getRoomNumber());
            result.setStartTime(response.getStartTime());
            result.setCustomerCount(response.getCustomerCount());
            result.setTollRules(response.getTollRules());
            result.setChargingId(response.getId());
            result.setPauseStartTime(response.getPauseStartTime());
            results.add(result);
        }
        return results;
    }
}
